package main

import (
	"fmt"
	"go_datastruct/lesson04/stack"
	"strconv"
)

func testStack() {
	s := stack.NewStack()
	for i := 1; i < 5; i++ {
		s.Push(i * 10)
	}
	s.PrintStack()
	s.Pop()
	fmt.Println("---------")
	s.PrintStack()
}
func IsOperator(ch byte) bool {
	return ch == '+' || ch == '-' || ch == '*' || ch == '/'
}
func Calculate(num1 int, num2 int, operator int) int {
	switch operator {
	case '+':
		return num1 + num2
	case '-':
		return num1 - num2
	case '*':
		return num1 * num2
	case '/':
		return num1 / num2
	default:
		panic("运算符错误")
	}
	return -1
}
func Priority(operator int) int {
	if operator == '*' || operator == '/' { // * / Priority is high
		return 1
	}
	return 0 // + -
}
func main() {
	expr := "3+5*6-2+1"
	numStack := stack.NewStack()
	operStack := stack.NewStack()
	for i := 0; i < len(expr); i++ {
		ch := expr[i]
		if IsOperator(ch) { // 操作符
			fmt.Println("is operator", ch, "==>", string(ch))
			//  判断operStack是否为空
			if !operStack.IsEmpty() {
				if Priority(operStack.Peek()) >= Priority(int(ch)) {
					num2 := numStack.Pop()
					num1 := numStack.Pop()
					op := operStack.Pop()
					var result = 0
					result = Calculate(num1, num2, op)
					fmt.Println("push result:", result)
					numStack.Push(result)
				}
				operStack.Push(int(ch))
			} else {
				operStack.Push(int(ch))
			}
		} else { // 数字
			// 数字入栈
			i, _ := strconv.Atoi(string(ch))
			fmt.Println("is number:", ch, "--->", i)
			numStack.Push(i)
		}
	}
	operStack.PrintStack()
	fmt.Println("--------")
	numStack.PrintStack()
	for {
		if !operStack.IsEmpty() {
			num2 := numStack.Pop()
			num1 := numStack.Pop()
			op := operStack.Pop()
			var result = 0
			result = Calculate(num1, num2, op)
			fmt.Println("push result:", result)
			numStack.Push(result)
		} else {
			break
		}

	}
	fmt.Println(numStack.Peek())
}
